
<template>
  <div class="c-upload">
    <!-- //.xls, .xlsx, .jpg,.jpeg, .png, .pdf, .doc, .docx, .zip, .rar -->
    <el-upload
      ref="uploadRef"
      class="upload-file"
      :name="name"
      :headers="headers"
      :action="action"
      :limit="limit"
      :file-list="dataFileList"
      multiple
      :accept="accept"
      :show-file-list="false"
      :on-exceed="handleExceed"
      :on-change="handleChange"
      :on-error="handleUploadError"
      :on-progress="handleProgress"
      :on-success="handleUploadSuccess"
      :before-upload="handleBeforeUpload"
      :before-remove="handleBeforeRemove"
    >
      <div class="c-upload-slot" :style="{textAlign: $scopedSlots.trigger?'center':'left'}">
        <div slot="trigger">
          <slot name="trigger">
            <el-button type="primary">{{ title }}</el-button>
          </slot>
        </div>
        <div>
          <slot name="default" />
        </div>
      </div>
      <div slot="tip" class="tip">
        <slot v-if="showTip" name="tip" v-bind="accept">
          <span>允许上传{{ accept }}格式文件</span>
        </slot>
      </div>
    </el-upload>
    <!-- 图片预览 -->
    <ImageView v-if="imgDialogVisible" :on-close="()=>imgDialogVisible=false" :url-list="[previewImg]" />
  </div>
</template>
<script>
import { getToken } from '@/utils/auth'
import request from '@/utils/request'
import { otherFiltersItem } from '@/utils'
// import { bus } from '@/utils/bus'
import { deleteShopAttachment, deleteBatch } from '@/api/common'
import { filterURL } from '@/utils'
import ImageView from 'element-ui/packages/image/src/image-viewer'

export default {
  name: 'CUpload',
  components: {
    ImageView
  },
  props: {
    value: {
      type: Array,
      default: () => []
    },
    data: {
      type: Array,
      default: () => []
    },
    showTip: {
      type: Boolean,
      default: false
    },
    action: {
      type: String,
      // default: () => '/ads-admin/api/v1/adsEnclosureInfo/uploadFile' // 附件默认上传路径
      default: () => `/slm-ctm/api/v1/file/uploadFile` // 附件默认上传路径
    },
    title: {
      type: String,
      default: '附件上传'
    },
    name: {
      type: String,
      default: 'file'
    },
    limit: {// 文件上传限制个数
      type: Number,
      default: 20
    },
    fileSize: {// 文件大小限制，单位mb
      type: Number,
      default: 300
    },
    beforeUpload: {
      type: Function,
      default: function() {
        return true
      }
    },
    beforeRemove: {
      type: Function,
      default: function() {
        return true
      }
    },
    perfix: {
      type: String,
      default: process.env.VUE_APP_IMG_PREFIX
    },
    attachmentType: {
      type: String,
      default: ''
    }, // 附件类型
    belongModel: {
      type: String,
      default: ''
    }, // 所属模块
    id: {
      type: String,
      default: ''
    },
    typeCode: {
      type: String,
      default: ''
    },
    modelId: {
      type: String,
      default: ''
    },
    renameFun: {
      type: Function,
      default: undefined
    },
    // 直接删除，不设置dr=1
    directDel: {
      type: Boolean,
      default: false
    }
  },
  inject: ['elFormItem'],
  data() {
    return {
      fileList: [],
      fileType: [],
      fileTemplateData: [],
      // 预览
      imgDialogVisible: false,
      previewImg: '',
      dataFileList: []
    }
  },
  computed: {
    accept() {
      return this.fileType.map(e => `.${e}`).join(',')
    },
    token() {
      return this.$store.getters.token
    },
    headers() {
      const t = this.token || getToken()
      return {
        'X-Token': t || '',
        'Authorization': t ? 'Bearer ' + t : ''
      }
    }
  },
  watch: {
    data: {
      handler(v) {
        this.dataFileList = this.data.map(file => {
          return {
            response: {
              data: file
            },
            name: file.attachmentName,
            url: file.attachmentUrl,
            percentage: 100,
            status: 'success',
            uid: file.id,
            flag: 'data'
          }
        })
        this.fileList = this.dataFileList
      },
      immediate: true
    },
    fileList: {
      handler(v) {
        this.$emit('input', v)
        this.$nextTick(() => {
          this.elFormItem && this.elFormItem.$emit('el.form.change')
        })
      },
      immediate: true,
      deep: true
    }
  },
  created() {
    this.getAttachmentType()
  },
  beforeDestroy() {
  },
  methods: {
    // 获取文件类型
    getAttachmentType() {
      if (this.attachmentType === '' && this.belongModel === '' && this.id === '' && this.typeCode === '') {
        this.$emit('template-success', [])
        return
      }
      const data = new FormData()
      const filtersRaw = []
      if (this.attachmentType) {
        const attachmentTypes = '[' + this.attachmentType + ']'
        filtersRaw.push(otherFiltersItem('attachmentType', attachmentTypes, 'in'))
      }
      if (this.belongModel) {
        const modles = '[' + this.belongModel + ']'
        filtersRaw.push(otherFiltersItem('belongModel', modles, 'in'))
      }
      if (this.id) {
        const ids = '[' + this.id + ']'
        filtersRaw.push(otherFiltersItem('id', ids, 'in'))
      }
      if (this.typeCode) {
        const typeCodes = '[' + this.typeCode + ']'
        filtersRaw.push(otherFiltersItem('typeCode', typeCodes, 'in'))
      }
      data.append('filtersRaw', JSON.stringify(filtersRaw))
      data.append('pageFlag', false)
      request({
        url: '/api/v1/configAttachmentTemplate/page',
        method: 'POST',
        data
      }).then(res => {
        if (res.data.records.length === 0) {
          return
        }
        const d = res.data.records
        this.fileTemplateData = d
        this.$emit('template-success', d)
        this.fileType = d.map(e => e.fileType).join(',').toLowerCase().replace('word', 'doc,docx').replace('excel', 'xlsx,xls').replace(/pptx?/g, 'ppt,pptx').split(',')
      })
    },
    getFileData(file) {
      const d = ((file.response || {}).data || {})
      const t = {
        // file
        ...file,
        attachmentName: d.attachmentName || file.name,
        attachmentUrl: d.attachmentUrl || '',
        createBy: d.createBy || '',
        createTime: d.createTime || '',
        id: d.id || file.uid,
        typeName: d.typeName || (file.name || '').split('.').pop(),
        belongModel: d.belongModel || '',
        attachmentType: d.attachmentType || '',
        configAttachmentId: d.configAttachmentId || ''
      }
      delete t.raw
      return t
    },
    handleExceed(files, fileList) {
      this.$message.warning(`最多只能上传 ${this.limit} 个文件`)
    },
    handleChange(file, fileList) {
      this.fileList = fileList
      this.$emit('file-change', file, fileList)
    },
    handleUploadError(err, file, fileList) {
      this.fileList = fileList
      this.$message.error('上传失败: ' + err)
      try {
        const res = JSON.parse(JSON.stringify(err))
        if (res.code === 401 || res.code === '401' || res.status === 401) {
          this.refreshToken({}, () => {})
        }
      } catch (error) {
        console.log(error)
      }
    },
    handleProgress(event, file, fileList) {

    },
    handleUploadSuccess(response, file, fileList) {
      if (response.success === 1) {
        if (this.fileTemplateData.length === 1) {
          this.$set(file.response.data, 'attachmentType', this.fileTemplateData[0].attachmentType)
          this.$set(file.response.data, 'belongModel', this.fileTemplateData[0].belongModel)
          this.$set(file.response.data, 'configAttachmentId', this.fileTemplateData[0].id)
        }
        if (this.renameFun instanceof Function) {
          fileList = fileList.forEach((e, i, arr) => {
            const name = this.renameFun(e, i, arr)
            if (name) {
              e.response.data.attachmentName = name
              e.name = name
            }
          })
        }
        this.fileList = fileList
        this.$emit('upload-success', response, file, fileList)
      } else {
        this.$message.error('上传失败: ' + response.msg)
        if (response.code === 401 || response.code === '401' || response.status === 401) {
          this.refreshToken({}, () => {})
        }
      }
    },
    handleBeforeUpload(file) {
      if (!this.attachmentType && !this.belongModel && !this.id && !this.typeCode) {
        return this.beforeUpload(file)
      }
      // 验证文件大小
      const size = (file.size || 0) / 1024 / 1024
      console.log('文件大小M', size, this.fileSize)
      if (size > this.fileSize) {
        this.$message.warning(`上传文件超过${this.fileSize}M大小限制`)
        return false
      }
      // 验证类型
      const fileType = file.name.split('.').pop().toLowerCase()
      if (!this.fileType.includes(fileType)) {
        // this.removeFile(file)
        let str = `只能上传${this.accept}类型的文件！`
        if (this.fileType.length === 0) {
          str = `${this.attachmentType}没有设置可上传的文件类型！`
        }
        this.$message.warning(str)
        return false
      }
      return this.beforeUpload(file)
    },
    handleBeforeRemove(file, fileList) {
      if (!this.beforeRemove(file, fileList)) {
        return false
      }
      return true
      // 前端不负责删除文件。。。。
      // eslint-disable-next-line no-unreachable
      if (file instanceof Array && (this.modelId !== '' || this.modelId !== undefined)) {
        return deleteBatch(file.filter(e => e.flag === 'data').map(e => e.response.data.id))
      }
      if (file.flag === 'data' && (this.modelId !== '' || this.modelId !== undefined)) {
        return deleteShopAttachment(file.response.data.id)
      }
      return true
    },
    // 合并fileList
    mergeFileList() {
      return []
    },
    // 删除文件
    removeFile(file) {
      let r = this.handleBeforeRemove(file, this.fileList)
      if (!(r instanceof Promise)) {
        if (r) {
          r = Promise.resolve(r)
        } else {
          r = Promise.reject(r)
        }
      }
      r.then(() => {
        if (!(file instanceof Array)) {
          file = [file]
        }
        const uids = file.map(e => e.uid)
        for (const uid of uids) {
          const fileList = this.fileList
          for (let i = 0; i < fileList.length; i++) {
            const item = fileList[i]
            // console.log(item, file)
            if (item.uid === uid) {
              if (!this.directDel && item.flag === 'data') {
                this.$set(item.response.data, 'dr', 1)
              } else {
                fileList.splice(i, 1)
              }
              break
            }
          }
        }
        this.$emit('remove', file)
      }).catch(() => {
        this.$message.error('删除失败！')
      })
    },
    clearFiles() {
      this.$refs.uploadRef.clearFiles()
    },
    abort(file) {
      this.$refs.uploadRef.abort(file)
      this.removeFile(file)
    },
    downFile(row) {
      const v = this.getFileData(row)
      this.$downFile(v)
    },
    closePreview() {
      this.imgDialogVisible = false
      this.previewImg = ''
    },
    preview(file) {
      file = this.getFileData(file)
      if (/^\.?jpe?g$|^\.?png$|^\.?gif$/.test(file.typeName)) {
      // 图片预览
        this.imgDialogVisible = true
        this.previewImg = filterURL(file.attachmentUrl)
      } else if (/^\.?docx?$|^\.?xlsx?$|^\.?pdf$|^\.?pptx?$/.test(file.typeName)) {
        window.open(process.env.VUE_APP_OFFICE_PREFIX + '?src=' + this.$getUrl(file), '_blank')
      } else {
        this.$message.warning('该文件类型不支持预览')
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.c-upload{
  display: inline-block;
  .c-upload-slot{
    text-align: left;
    &>div{
      display: inline-block;
    }
  }
  /deep/ .el-upload{
    width: 100% !important;
    text-align: left;
  }
}
</style>
